#pragma once
#include "funciton_traits.h"
#include "type_id.h"
#include <string>
#include <iostream>
#include <string.h>
using namespace Temp;

template<typename DecayedArgList >
struct CTest;
template<typename... ArgsList>
struct CTest<TypeList<ArgsList...>>
{
public:
	template<typename Func,typename... T>
	static void fun(Func f,std::tuple<T...>& t)
	{
		std::cout <<"sizeof="<< sizeof...(ArgsList) << std::endl;
		f(std::get<ArgsList>(t)...);
	}
	template<typename Func>
	static void funt(Func f)
	{
		std::cout <<"sizeof="<< sizeof...(ArgsList) << std::endl;
        char* buf = new char[10];
        new (buf)int(10086);
        memcpy( buf+4,"ABCDE\0",6);

        auto t = std::make_tuple(reinterpret_cast<ArgsList>(buf)...);

		f(std::get<ArgsList>(t)...);
	}
};



class MyClass
{
public:
	template<typename Fun>
	void Test(Fun f)
	{
        std::cout<<" before sizeof="<< FunctionTraits<Fun>::paramCount<<std::endl;

		std::tuple<int,std::string,float> param = std::make_tuple(1, "hello world",1.0f);
		CTest<typename FunctionTraits<Fun>::ArgList>::fun(f,param);
	}
	template<typename Fun>
	void TestT(Fun f)
	{
        std::cout<<" before sizeof="<< FunctionTraits<Fun>::paramCount<<std::endl;
		//std::tuple<int,std::string,float> param = std::make_tuple(1, "hello world",1.0f);

		std::tuple<int,int,std::string,float> param = std::make_tuple(1,2, "hello world",1.0f);
		CTest<typename FunctionTraits<Fun>::ArgList>::funt(f);
	}

	void Run()
	{
		Test([](int a, std::string b)
			{
				std::cout << a << "\t" << b << std::endl;
			});
        TestT([](int* a,char* b)
              {
                  std::cout <<"[](int a,int b) \t"<< *a << "\t" << b << std::endl;
              });
	    auto type_id = TypeID<int>;
        std::cout<<"type_id="<<type_id<<std::endl;
        std::cout<<"type_id="<<TypeID<float><<std::endl;
        std::cout<<"type_id="<<TypeID<MyClass><<std::endl;
	}
};

